// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成

package com.fowo.api.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.*;
import com.fowo.api.inventory.model.InventoryStorageVo;
import com.fowo.api.inventory.model.SimpleInventoryItem;
import com.fowo.api.inventory.model.TargetTypeEnum;
import com.fowo.api.inventory.model.form.InventoryStorageFormVo;
import com.fowo.api.inventory.service.impl.InventoryBusinessServiceImpl;
import com.fowo.api.model.stock.in.StockInPushPayableAction;
import com.fowo.api.model.stock.in.StockInVo;
import com.fowo.api.model.stock.in.product.StockInProductItemVo;
import com.fowo.api.model.stock.in.product.StockInProductSearchParamPo;
import com.fowo.api.model.stock.in.product.StockInProductVo;
import com.fowo.api.sys.annotation.DataActivity;
import com.fowo.api.sys.entity.SysDict;
import com.fowo.api.sys.entity.SysDictItem;
import com.fowo.api.sys.entity.enums.SysDataActivityAction;
import com.fowo.api.sys.mapper.SysDictItemMapper;
import com.fowo.api.sys.mapper.SysDictMapper;
import com.fowo.api.user.model.JwtUserInfo;

import java.math.BigDecimal;
import java.util.*;
import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

/**
 * 入库单 服务实现类
 */
@Service
@Slf4j
@DS("ds24")
public class StockInServiceImpl
        extends StockInBaseServiceImpl {

    @Resource
    private ProductSupplierQuoteServiceImpl productSupplierQuoteService;
    @Resource
    private ProductPriceServiceImpl productPriceService;
    @Autowired(required = false)
    protected StockInPushPayableAction stockInPushPayableAction;
    @Resource
    private ProductServiceImpl productService;
    @Resource
    private ListingFatherServiceImpl listingFatherService;
    @Resource
    private SysDictMapper sysDictMapper;
    @Resource
    private SysDictItemMapper sysDictItemMapper;
    @Resource
    private PurchaseOrderServiceImpl purchaseOrderService;
    @Resource
    protected PurchaseOrderProductServiceImpl purchaseOrderProductService;

    @DataActivity(action = SysDataActivityAction.Del)
    @Override
    public boolean delete(Long id) throws Exception {
        StockInVo voById = this.getVoById(id);
//        Assert.isTrue(voById.getStatus().equals("0"),"已审核不能删除!");
        return this.removeById(id);
    }

    @DataActivity(action = SysDataActivityAction.Add)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long create(StockInVo model) throws Exception {

        if (model.getWarehousingDate() == null) {
            model.setWarehousingDate(new Date());
        }
        for (int i = 0; i < model.getProductList().size(); i++) {
            StockInProductItemVo stockInProductItemVo = model.getProductList().get(i);
            if (stockInProductItemVo.getFnsku() != null) {
                ListingFather byId = listingFatherService.getById(stockInProductItemVo.getFnsku());
                if (stockInProductItemVo.getLxFnsku() == null) {
                    stockInProductItemVo.setLxFnsku(byId.getFnsku());
                }

            }
        }
        this.calcUnitStock(model);
        Long aLong = super.create(model);
        //修改销售价格
        StockInProductSearchParamPo productListSearchParamPo = new StockInProductSearchParamPo();
        productListSearchParamPo.setParentStockInId(aLong);
        List<StockInProductItemVo> search = stockInProductService.search(productListSearchParamPo);
        for (int i = 0; i < search.size(); i++) {
            StockInProductItemVo stockInProductItemVo = search.get(i);
            StockInProductVo model1 = new StockInProductVo();
            model1.setId(stockInProductItemVo.getId());
            Long productId = stockInProductItemVo.getProductId();
            Product byId = productService.getById(productId);
            if (byId != null && byId.getClassify() != null) {
                ProductPrice one = productPriceService.getOne(Wrappers.<ProductPrice>query().lambda().eq(ProductPrice::getProductGroup, byId.getClassify()));
                if (one != null) {
                    if (one.getPriceType().equals("0")) {
                        BigDecimal add = stockInProductItemVo.getUnitPrice().add(stockInProductItemVo.getUnitPrice().multiply(one.getPriceCoefficient().divide(new BigDecimal("100"))));
                        model1.setSellPrice(add);
                    } else if (one.getPriceType().equals("1")) {
                        model1.setSellPrice(one.getPrice());
                    }
                    stockInProductService.update(model1);
                }
            }
        }
        return aLong;
    }

    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了撤销操作"
    )
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void custCancelAudit(Long id) throws Exception {
        StockInVo vo = getVoById(id);
        super.custCancelAudit(id);
        //判断入库单是否是采购订单
        if (vo.getPurchaseOrderCode() != null) {
            //查询订单
            PurchaseOrder one = purchaseOrderService.getOne(Wrappers.<PurchaseOrder>query().lambda()
                    .eq(PurchaseOrder::getPurchaseOrderCode, vo.getPurchaseOrderCode()));
            one.setAnStatus("9");
            //arrivalStatus
            one.setArrivalStatus("1");
            Assert.notNull(one, "采购订单不存在!");
            List<StockInProductItemVo> productList = vo.getProductList();
            BigDecimal add = new BigDecimal("0");
            for (int i = 0; i < productList.size(); i++) {
                StockInProductItemVo stockInProductItemVo = productList.get(i);
                PurchaseOrderProduct one1 = purchaseOrderProductService.getById(stockInProductItemVo.getPurchaseOrderProductId());
                Assert.notNull(stockInProductItemVo.getQuantity(), "没有质检,请先质检!");
                Assert.isTrue(stockInProductItemVo.getQuantity() > 0, "没有质检,请先质检!");
                Assert.notNull(one1, "产品不存在!");
                Integer quantity = stockInProductItemVo.getQuantity();
                add = add.add(new BigDecimal(quantity));
                //到货量quantity_received
                one1.setQuantityReceived(one1.getQuantityReceived() - quantity);
                //收货量quantity_receive
                one1.setQuantityReceive(one1.getQuantityReceive() + quantity);
                //退货量cross_checking
                one1.setCrossChecking(one1.getCrossChecking() - quantity);

                purchaseOrderProductService.updateById(one1);

            }
            long l = new BigDecimal(one.getQuantityReceived()).subtract(add).longValue();
            one.setQuantityReceived(l);
            purchaseOrderService.updateById(one);
        }

    }

    @DataActivity(action = SysDataActivityAction.Modified)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(StockInVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        StockIn entity = this.getById(model.getId());
        if (entity == null) {
            throw new Exception("入库单不存在");
        }
        this.calcUnitStock(model);
        BeanUtils.copyProperties(
                model,
                entity,
                "id",
                "totalAmount",
                "totalNum",
                "createTime",
                "createUser",
                "lastUpdateTime",
                "lastUpdateUser"
        );
        entity.setLastUpdateTime(new Date());
        if (currentUser != null) {
            entity.setLastUpdateUser(currentUser.getUserId());
        }
        if (this.updateById(entity)) {
            updateAllChilds(model);
            baseMapper.updateCalcFields(entity.getId());
            return true;
        }
        return false;
    }

    /**
     * 重算可用量
     *
     * @param model
     */
    public void calcUnitStock(StockInVo model) {
        try {
            final List<StockInProductItemVo> productList = model.getProductList();
            for (StockInProductItemVo stockInProductItemVo : productList) {
                    stockInProductItemVo.setUnitStock(Convert.toInt(NumberUtil.add(stockInProductItemVo.getDefectiveProduct(), stockInProductItemVo.getQuantity(), stockInProductItemVo.getWaitQuantity()), 0));
            }
            model.setTotalStorage(Convert.toStr(NumberUtil.add(productList.stream().map(StockInProductItemVo::getUnitStock).toArray(Integer[]::new)), "0"));
        } catch (Exception ex) {
        }
    }

    /**
     * 获取详情
     *
     * @param id 入库单的主键
     */
    @DataActivity(action = SysDataActivityAction.View)
    @Override
    public StockInVo getVoById(Long id) throws Exception {
        StockInVo vo = this.baseMapper.selectVoById(id);
        if (vo == null) {
            return null;
        }
        StockInProductSearchParamPo productListSearchParamPo = new StockInProductSearchParamPo();
        productListSearchParamPo.setParentStockInId(id);
        vo.setProductList(stockInProductService.search(productListSearchParamPo));
        //读取领星的价格
        List<StockInProductItemVo> search = stockInProductService.search(productListSearchParamPo);
        if (vo.getStatus() != null) {

//            for(int i=0;i<search.size();i++){
//                StockInProductItemVo stockInProductItemVo = search.get(i);
//                ProductSupplierQuote one = productSupplierQuoteService.getOne(Wrappers.<ProductSupplierQuote>query().lambda()
//                        .eq(ProductSupplierQuote::getParentProduct, stockInProductItemVo.getProductId())
//                        .eq(ProductSupplierQuote::getSupplierId, vo.getSupplier()));
//                if(one!=null){
//                    //设置工费的价格
//                    stockInProductItemVo.setLaborCosts(one.getLaborCost());
//                    stockInProductItemVo.setUnitPrice(one.getPrice());
//                    stockInProductItemVo.setMainUnitPrice(one.getSilverPrices());
//                    stockInProductItemVo.setGramWeight(one.getSilverWeight());
//                }
////                List<ProductPrice> list = productPriceService.list(Wrappers.<ProductPrice>query().lambda().eq(ProductPrice::getSku, stockInProductItemVo.getSku()));
////                if(list.size()>0){
////                    ProductPrice productPrice = list.get(0);
////                    if(productPrice.getPriceType().equals("1")){
////                        stockInProductItemVo.setUnitPrice(productPrice.getPrice());
////                    }else{
////                        stockInProductItemVo.setUnitPrice(productPrice.getPrice().multiply(productPrice.getPriceCoefficient()));
////                    }
////                }
//            }

        }

        vo.setProductList(search);
        return vo;
    }


    public void batchPushPy(List<Long> ids) throws Exception {
        for (int i = 0; i < ids.size(); i++) {
            Long aLong = ids.get(i);
            stockInPushPayableAction.run(aLong);
        }
    }

    /**
     * 准备用于 入库 的参数
     */
    @Override
    protected InventoryStorageFormVo prepareRuku(StockInVo vo) throws Exception {
        if (!"0".equals(vo.getStatus())) {
            throw new Exception("当前单据状态不可进行此操作！");
        }
        InventoryStorageFormVo formVo = new InventoryStorageFormVo();
        formVo.setTo(TargetTypeEnum.Normal);
        formVo.setFormNum(vo.getOrderSn());

        final SysDict dict = sysDictMapper.selectOne(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getDictCode, "SCM00001"));
        final List<SysDictItem> itemList = sysDictItemMapper.selectList(Wrappers.lambdaQuery(SysDictItem.class).eq(SysDictItem::getDictId, dict.getId()));
        final SysDictItem dictItem = itemList.stream().filter(i -> i.getItemValue().equals(vo.getReceiptType())).findFirst().get();
        formVo.setDocumentType(dictItem.getItemText());

        formVo.setFormOperator(vo.getCreateUser().toString());
        if (ObjectUtils.isEmpty(vo.getWarehouse())) {
            throw new Exception("仓库 为空");
        }
        formVo.setStockId(vo.getWarehouse());
        for (StockInProductItemVo stockInProduct : vo.getProductList()) {
            if (ObjUtil.isEmpty(stockInProduct.getPositions())) {
                Long id = SpringUtil.getBean(InventoryBusinessServiceImpl.class).getSearchByWarehouseBin(vo.getWarehouse(), Convert.toStr(stockInProduct.getShopId()), stockInProduct.getLxFnsku(), stockInProduct.getProductId(), 1);
                stockInProduct.setPositions(id);
            }
            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(stockInProduct.getProductId());
            InventoryStorageVo storageItem = new InventoryStorageVo();
            storageItem.setItem(inventoryItem);
            storageItem.setQty(String.valueOf(stockInProduct.getQuantity()).equals("null") ? BigDecimal.valueOf(0) : BigDecimal.valueOf(stockInProduct.getQuantity()));
            storageItem.setShopId(String.valueOf(stockInProduct.getShopId()).equals("null") ? null : String.valueOf(stockInProduct.getShopId()));
            storageItem.setFnSku(String.valueOf(stockInProduct.getLxFnsku()).equals("null") ? null : String.valueOf(stockInProduct.getLxFnsku()));
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(stockInProduct.getPositions(), Integer.parseInt(String.valueOf(stockInProduct.getQuantity()).equals("null") ? "0" : String.valueOf(stockInProduct.getQuantity())));
            storageItem.setBinIds(binIds);
            storageItem.setFromBinIdsType(TargetTypeEnum.Normal);
            storageItem.setCustomId(vo.getId());
            storageItem.setCustomBdId(stockInProduct.getId());
            formVo.add(storageItem);
        }
        super.update(vo);
        return formVo;
    }

    /**
     * 准备用于 入库次品 的参数
     */
    @Override
    protected InventoryStorageFormVo prepareRukucipin(StockInVo vo) throws Exception {
        if (!"1".equals(vo.getStatus())) {
            throw new Exception("当前单据状态不可进行此操作！");
        }
        InventoryStorageFormVo formVo = new InventoryStorageFormVo();
        formVo.setTo(TargetTypeEnum.Defect);
        formVo.setFormNum(vo.getOrderSn());

        final SysDict dict = sysDictMapper.selectOne(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getDictCode, "SCM00001"));
        final List<SysDictItem> itemList = sysDictItemMapper.selectList(Wrappers.lambdaQuery(SysDictItem.class).eq(SysDictItem::getDictId, dict.getId()));
        final SysDictItem dictItem = itemList.stream().filter(i -> i.getItemValue().equals(vo.getReceiptType())).findFirst().get();
        formVo.setDocumentType(dictItem.getItemText());

        formVo.setFormOperator(vo.getCreateUser().toString());
        if (ObjectUtils.isEmpty(vo.getWarehouse())) {
            throw new Exception("仓库 为空");
        }
        formVo.setStockId(vo.getWarehouse());
        for (StockInProductItemVo stockInProduct : vo.getProductList()) {
            if (ObjUtil.isEmpty(stockInProduct.getDefectiveProductPosition())) {
                Long id = SpringUtil.getBean(InventoryBusinessServiceImpl.class).getSearchByWarehouseBin(vo.getWarehouse(), Convert.toStr(stockInProduct.getShopId()), stockInProduct.getLxFnsku(), stockInProduct.getProductId(), 2);
                stockInProduct.setDefectiveProductPosition(id);
            }
            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(stockInProduct.getProductId());
            InventoryStorageVo storageItem = new InventoryStorageVo();
            storageItem.setItem(inventoryItem);
            storageItem.setQty(String.valueOf(stockInProduct.getDefectiveProduct()).equals("null") ? BigDecimal.valueOf(0) : BigDecimal.valueOf(stockInProduct.getDefectiveProduct()));
            storageItem.setShopId(String.valueOf(stockInProduct.getShopId()).equals("null") ? null : String.valueOf(stockInProduct.getShopId()));
            storageItem.setFnSku(String.valueOf(stockInProduct.getLxFnsku()).equals("null") ? null : String.valueOf(stockInProduct.getLxFnsku()));
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(stockInProduct.getDefectiveProductPosition(), Integer.parseInt(String.valueOf(stockInProduct.getDefectiveProduct()).equals("null") ? "0" : String.valueOf(stockInProduct.getDefectiveProduct())));
            storageItem.setBinIds(binIds);
            storageItem.setFromBinIdsType(TargetTypeEnum.Normal);
            storageItem.setCustomId(vo.getId());
            storageItem.setCustomBdId(stockInProduct.getId());
            formVo.add(storageItem);
        }
        super.update(vo);
        return formVo;
    }


}
